home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2001 May / SGI Freeware 2001 May - Disc 3.iso / dist / fw_expect.idb / usr / freeware / bin / mkpasswd.z / mkpasswd
Text File  |  1999-01-26  |  5KB  |  204 lines

  1. #!/usr/freeware/bin/expect --
  2. # mkpasswd - make a password, if username given, set it.
  3. # Author: Don Libes, NIST
  4.  
  5. # defaults
  6. set length 9
  7. set minnum 2
  8. set minlower 2
  9. set minupper 2
  10. set verbose 0
  11. set distribute 0
  12.  
  13. if [file executable /bin/yppasswd] {
  14.     set defaultprog /bin/yppasswd
  15. } elseif [file executable /bin/passwd] {
  16.     set defaultprog /bin/passwd
  17. } else {
  18.     set defaultprog passwd
  19. }
  20. set prog $defaultprog
  21.  
  22. while {[llength $argv]>0} {
  23.     set flag [lindex $argv 0]
  24.     switch -- $flag \
  25.     "-l" {
  26.         set length [lindex $argv 1]
  27.         set argv [lrange $argv 2 end]
  28.     } "-d" {
  29.         set minnum [lindex $argv 1]
  30.         set argv [lrange $argv 2 end]
  31.     } "-c" {
  32.         set minlower [lindex $argv 1]
  33.         set argv [lrange $argv 2 end]
  34.     } "-C" {
  35.         set minupper [lindex $argv 1]
  36.         set argv [lrange $argv 2 end]
  37.     } "-v" {
  38.         set verbose 1
  39.         set argv [lrange $argv 1 end]
  40.     } "-p" {
  41.         set prog [lindex $argv 1]
  42.         set argv [lrange $argv 2 end]
  43.     } "-2" {
  44.         set distribute 1
  45.         set argv [lrange $argv 1 end]
  46.     } default {
  47.         set user [lindex $argv 0]
  48.         set argv [lrange $argv 1 end]
  49.         break
  50.     }
  51. }
  52.  
  53. if {[llength $argv]} {
  54.     puts "usage: mkpasswd \[args] \[user]"
  55.     puts "  where arguments are:"
  56.     puts "    -l #      (length of password, default = $length)"
  57.     puts "    -d #      (min # of digits, default = $minnum)"
  58.     puts "    -c #      (min # of lowercase chars, default = $minlower)"
  59.     puts "    -C #      (min # of uppercase chars, default = $minupper)"
  60.     puts "    -v        (verbose, show passwd interaction)"
  61.     puts "    -p prog   (program to set password, default = $defaultprog)"
  62.     exit 1
  63. }
  64.  
  65. if {$minnum + $minlower + $minupper > $length} {
  66.     puts "impossible to generate $length-character password\
  67.         with $minnum numbers, $minlower lowercase letters,\
  68.         and $minupper uppercase letters"
  69.     exit 1
  70. }
  71.  
  72. # if there is any underspecification, use additional lowercase letters
  73. set minlower [expr $length - ($minnum + $minupper)]
  74.  
  75. set lpass ""        ;# password chars typed by left hand
  76. set rpass ""        ;# password chars typed by right hand
  77.  
  78. # insert char into password at a random position
  79. proc insert {pvar char} {
  80.     upvar $pvar p
  81.  
  82.     set p [linsert $p [rand [expr 1+[llength $p]]] $char]
  83. }
  84.  
  85. set _ran [pid]
  86.  
  87. proc rand {m} {
  88.     global _ran
  89.  
  90.     set period 259200
  91.     set _ran [expr ($_ran*7141 + 54773) % $period]
  92.     expr int($m*($_ran/double($period)))
  93. }
  94.  
  95. # choose left or right starting hand
  96. set initially_left [set isleft [rand 2]]
  97.  
  98. # given a size, distribute between left and right hands
  99. # taking into account where we left off
  100. proc psplit {max lvar rvar} {
  101.     upvar $lvar left $rvar right
  102.     global isleft
  103.  
  104.     if {$isleft} {
  105.         set right [expr $max/2]
  106.         set left [expr $max-$right]
  107.         set isleft [expr !($max%2)]
  108.     } else {
  109.         set left [expr $max/2]
  110.         set right [expr $max-$left]
  111.         set isleft [expr $max%2]
  112.     }
  113. }
  114.  
  115. if {$distribute} {
  116.     set lkeys {q w e r t a s d f g z x c v b}
  117.     set rkeys {y u i o p h j k l n m}
  118.     set lnums {1 2 3 4 5 6}
  119.     set rnums {7 8 9 0}
  120. } else {
  121.     set lkeys {a b c d e f g h i j k l m n o p q r s t u v w x y z}
  122.     set rkeys {a b c d e f g h i j k l m n o p q r s t u v w x y z}
  123.     set lnums {0 1 2 3 4 5 6 7 8 9}
  124.     set rnums {0 1 2 3 4 5 6 7 8 9}
  125. }
  126.  
  127. set lkeys_length [llength $lkeys]
  128. set rkeys_length [llength $rkeys]
  129. set lnums_length [llength $lnums]
  130. set rnums_length [llength $rnums]
  131.  
  132. psplit $minnum left right
  133. for {set i 0} {$i<$left} {incr i} {
  134.     insert lpass [lindex $lnums [rand $lnums_length]]
  135. }
  136. for {set i 0} {$i<$right} {incr i} {
  137.     insert rpass [lindex $rnums [rand $rnums_length]]
  138. }
  139.  
  140. psplit $minlower left right
  141. for {set i 0} {$i<$left} {incr i} {
  142.     insert lpass [lindex $lkeys [rand $lkeys_length]]
  143. }
  144. for {set i 0} {$i<$right} {incr i} {
  145.     insert rpass [lindex $rkeys [rand $rkeys_length]]
  146. }
  147.  
  148. psplit $minupper left right
  149. for {set i 0} {$i<$left} {incr i} {
  150.     insert lpass [string toupper [lindex $lkeys [rand $lkeys_length]]]
  151. }
  152. for {set i 0} {$i<$right} {incr i} {
  153.     insert rpass [string toupper [lindex $rkeys [rand $rkeys_length]]]
  154. }
  155.  
  156. # merge results together
  157. if {$initially_left} {
  158.     regexp "(\[^ ]*) *(.*)" "$lpass" x password lpass
  159.     while {[llength $lpass]} {
  160.         regexp "(\[^ ]*) *(.*)" "$password$rpass" x password rpass
  161.         regexp "(\[^ ]*) *(.*)" "$password$lpass" x password lpass
  162.     }
  163.     if {[llength $rpass]} {
  164.         append password $rpass
  165.     }        
  166. } else {
  167.     regexp "(\[^ ]*) *(.*)" "$rpass" x password rpass
  168.     while {[llength $rpass]} {
  169.         regexp "(\[^ ]*) *(.*)" "$password$lpass" x password lpass
  170.         regexp "(\[^ ]*) *(.*)" "$password$rpass" x password rpass
  171.     }
  172.     if {[llength $lpass]} {
  173.         append password $lpass
  174.     }        
  175. }
  176.  
  177. if {[info exists user]} {
  178.     if {!$verbose} {
  179.         log_user 0
  180.     }
  181.  
  182.     spawn $prog $user
  183.     expect {
  184.         "assword*:" {
  185.             # some systems say "Password (again):"
  186.             send "$password\r"
  187.             exp_continue
  188.         }
  189.     }
  190.  
  191.     # if user isn't watching, check status
  192.     if {!$verbose} {
  193.         if {[lindex [wait] 3]} {
  194.             puts -nonewline "$expect_out(buffer)"
  195.             exit 1
  196.         }
  197.     }
  198. }
  199.  
  200. if {$verbose} {
  201.     puts -nonewline "password for $user is "
  202. }
  203. puts "$password"
  204.